#pragma once

/*
+-------------------+------------------------+-------------------+
| prependable bytes |  readable bytes        |  writable bytes   |
|                   |     (CONTENT)          |                   |
+-------------------+------------------------+-------------------+
|                   |                        |                   |
0      <=      readerIndex_   <=   writerIndex_      <=     size()
 */

#include <sys/uio.h>

#include <unistd.h>
#include <algorithm>
#include <cstddef>
#include <cstring>
#include <string>
#include <vector>

static const size_t PrependSize = 8;    // 默认prependable空间大小
static const size_t BufferSize = 1024;  // 默认Buffer大小

class Buffer {
private:
    char* Begin();

    void MakeSpace(size_t len);

    void EnSureWriteableBytes(size_t len);

public:
    Buffer(int initsize = BufferSize);

    size_t ReadableBytes();
    size_t WriteableBytes();
    size_t PrependableBytes();

    // 返回缓冲区可读数据起始地址
    char* Peek();

    // 标记数据已消费
    void Retrieve(size_t len);

    void RetrieveAll();

    // 把onMessage函数上报的Buffer数据转成string类型的数据返回
    std::string RetrieveAsString(size_t len);

    std::string RetrieveAllAsString();

    // 把[data, data+len]内存上的数据添加到writeable缓冲区当中
    void Append(const char* data, size_t len);

    int ReadFd(int fd);
    int WriteFd(int fd);

    /* About HTTP */
    const static char CRLF[];
    const char* FindCRLF() {
        const char* pos = std::search(Peek(), Peek() + ReadableBytes(), CRLF, CRLF + 2);
        return pos;
    }

private:
    size_t read_index_;
    size_t write_index_;
    std::vector<char> buffer_;
};